<?php
namespace  app\dao;

use Yii;
use yii\db\Query;
use yii\db\Command;
use yii\base\Object;
use yii\db\ActiveRecord;
use app\enum\EnumOther;
use app\models\AdminLog;

class BaseDAO extends ActiveRecord
{
    private static $_instance = [];
    protected $_table = '';
    protected $_pKey = 'id';
    protected $_name = '';
    protected $_dFlag = 'delete_flag';
    protected $_created = 'create_time';
    protected $_updated = 'modify_time';
    protected static $paramAlias =':p';

    /**
     * @desc 单例
     * @author liaojianwen
     * @date 2016-10-24
     */
    public static function getInstance()
    {
        $className = get_called_class();

        if (!isset(self::$_instance[$className])){
            self::$_instance[$className] = new static ();
		}
		
		return self::$_instance [$className];
	}
	public function __construct()
	{
	}

       /**
	    * @desc 根据条件获取单条数据
	    * @param $field string 'id,user_id,order_id'
	    * @param $condition 'id=>:id' or array('id'=>1);
	    * @param $params [':id'=>1]
	    * @author liaojianwen
	    * @date 2016-10-24
       */
    public function findByAttributes($field = '*',$condition = false, $params= [], $order = false)
    {
		try {
			$query = new Query ();
			$query->select ( $field )->from ( $this->_table );
			if ($condition) {
				if (! empty ( $params )) {
					$query->where ( $condition, $params );
				} else {
					$query->where ( $condition );
				}
			}
			if ($order) {
				$query->orderBy ( $order );
			}
			return $query->one ();
		} catch ( \Exception $e ) {
			return false;
		}
    }

    /**
    *@desc 根据条件获取全部数据
    *@param $field string eg ：'id,user_id,order_id'
    *@param $condition eg :'id=>:id' or array('id'=>1);
    *@param $params eg :[':id'=>1]
    *@author liaojianwen
    *@date 2016-10-24
    */
    public function findAllByAttributes($field='*',$condition = false, $params=[], $order = false,$limit = 0,$page = 0)
    {
		try {
			$result = [ 
					'list' => [ ],
					'page' => 0,
					'pageSize' => 0,
					'count' => 0 
			];
			$query = new Query ();
			$query->select ( $field )->from ( $this->_table );
			if ($condition) {
				if (! empty ( $params )) {
					$query->where ( $condition, $params );
				} else {
					$query->where ( $condtion );
				}
			}
			if ($order) {
				$query->orderBy ( $order );
			}
			if ($limit) {
				$result ['pageSize'] = ( int ) $limit;
				
				if ($page) {
					$query->offset ( ($page - 1) * $limit );
					
					$result ['page'] = ( int ) $page;
				}
			}
			$result ['count'] = ( int ) $query->count ();
			$result ['list'] = $query->all ();
	
			return $result;
		} catch ( \Exception $e ) {
			return $e->getMessage();
			return false;
		}
    }

    /**
    *@desc 根据主键获取数据
    *@params $pk  主键 //array or int
    *@params $field 查询字段 //1，2，3..
    *@author liaojianwen
    *@date 2016-10-24
    *@return mix array;
    */
    public function findByPk($pk, $field='*') 
   {
		try {
			$query = new Query ();
			$query->select ( $field )->from ( $this->_table );
			if (is_array ( $pk )) {
				return $query->where ( [ 
						'in',
						$this->_pKey,
						$pk 
				] )->all ();
			} else {
				return $query->where ( $this->_pKey . ' = :id', [ 
						':id' => $pk 
				] )->one ();
			}
		} catch ( \Exception $e ) {
			return false;
		}
	}
	
	/**
	 * @desc 省去表名select
	 * @param mixed $fields a string (e.g. "id, name") or an array (e.g. array('id', 'name'))
	 * @param mixed $conditions the conditions that should be put in the WHERE part.
	 * @param array $params the parameters (name=>value) to be bound to the query
	 * @param mixed $queryType all/one/scalar
	 * @param mixed $order string (e.g. "id ASC, name DESC") or an array (e.g. array('id ASC', 'name DESC')).
	 * @param array $joinArray join参数 [
	 * 									[	$table, 
	 * 										$conditions, 
	 * 										$params,
	 * 										'left'=>'']
	 * 									,...
	 * 								  ]
	 * @param string $tableAlias 主表别名
	 * @param int $limit the limit
	 * @param int $offset the offset
	 * @param mixed $groups
	 * @author liaojianwen
	 * @date 2016-11-4
	 * @return boolean|Ambigous <multitype:, mixed>|mixed
	 */
	public function iselect($fields, $conditions, $params, $queryType = 'all', $order = '', $joinArray = array(), $tableAlias = '', $limit = null, $offset = null, $groups = '')
    {
    	if (empty($fields) || empty($conditions)) {
    		return false;
    	}
		try {
			$query = new Query ();
			if (empty ( $tableAlias )) {
				$query->select ( $fields )->from ( $this->_table );
			} else {
				$query->select ( $fields )->from ( $this->_table . ' ' . $tableAlias );
			}
			if (empty ( $params )) {
				$query->where ( $conditions );
			} else {
				$query->where ( $conditions, $params );
			}
			if (! empty ( $order )) {
				$query->orderBy ( $order );
			}
			if (is_array ( $joinArray ) && ! empty ( $joinArray )) {
				foreach ( $joinArray as $joinUnit ) {
					if (isset ( $joinUnit [0] ) && isset ( $joinUnit [1] )) {
						if (! isset ( $joinUnit [2] )) {
							$joinUnit [2] = [ ];
						}
						if (isset ( $joinUnit ['left'] )) {
							$query->leftJoin( $joinUnit [0], $joinUnit [1], $joinUnit [2] );
						} elseif (isset ( $joinUnit ['right'] )) {
							$query->rightJoin( $joinUnit [0], $joinUnit [1], $joinUnit [2] );
						} else {
							$query->innerJoin( $joinUnit [0], $joinUnit [1], $joinUnit [2] );
						}
					}
				}
			}
			if (empty ( $groups )) {
				$query->groupBy ( $groups );
			}
			if (empty ( $offset )) {
				$query->offset ( $offset );
			}
			if (empty ( $limit )) {
				$query->limit ( $limit );
			}
			if ($queryType == 'all') {
				return $query->all ();
			} else if ($queryType == 'one') {
				return $query->one ();
			} else if ($queryType == 'scalar') {
				return $query->scalar ();
			}
		} catch ( \Exception $e ) {
			dd($e->getMessage());
			return false;
    	}
    }
    
    /**
     * @desc 省去表名插入数据
     * @param  $columns array
     * @param boolean $returnpk
     * @author liaojianwen
     */
    public function iinsert($columns, $returnpk = false)
    {
    	try {
			if (empty ( $columns )) {
				return false;
			}
			if (! empty($this->_created) && ! isset($columns[$this->_created])) {
				$columns[$this->_created] = time();
			}
			$command = Yii::$app->db;
			$sql = $command->createCommand ()->insert ( $this->_table, $columns )->getRawSql();
			//操作记录--start
			$route = Yii::$app->controller->route;
			$controller = Yii::$app->controller->id;
			$action = Yii::$app->controller->action->id;
			AdminLog::saveLog($controller, $action, $route, $sql);
			//--end
			$result = $command->createCommand($sql)->execute ();
			if ($result != 0) {
				if ($returnpk) {
					return $command->getLastInsertID ();
				} else {
					return true;
				}
			} else {
				return false;
			}
		} catch ( \Exception $e ) {
			dd($e->getMessage());
			return false;
		}
	}
	/**
	 * @desc 省去表名更新数据
	 * @param array $columns
	 * @param string|array $conditions 
	 * @param [] $params
	 * @return boolean
	 */
	public function iupdate($columns, $conditions, $params) 
	{
		try {
			if (! empty ( $columns ) && ! empty ( $conditions )) {
				$command = Yii::$app->db;
				if (! empty($this->_updated) && ! isset($columns[$this->_updated])) {
					$columns[$this->_updated] = time();
				}
				$sql = $command->createCommand ()->update ( $this->_table, $columns, $conditions, $params )->getRawSql();
				//操作记录
				$route = Yii::$app->controller->route;
				$controller = Yii::$app->controller->id;
				$action = Yii::$app->controller->action->id;
				AdminLog::saveLog($controller, $action, $route, $sql);
				$return = $command->createCommand($sql)->execute ();
				return $return;
				
			}
			return false;
		} catch ( \Exception $e ) {
			dd($e->getMessage());
			return false;
		}
	}
	
	/**
	 * @desc 根据主键更新数据
	 * @param int | array $pk 主键
	 * @param [] $columns
	 * @author liaojianwen
	 * @date 2016-11-4
	 * @return $affectRows
	 */
	public function updateByPk($pk,$columns)
	{
		if($this->isParamsEmpty($pk, $columns) || !is_array($columns)){
			return false;
		}
		try{
			$command = Yii::$app->db;
			if (is_array ( $pk )) {
				$setValues = [ ];
				$idsExpress = '';
				$j = count ( $pk );
				for($i = $j - 1; $i >= 0; $i --) {
					$idsExpress .= ($idsExpress ? ',' : '') . self::$paramAlias . $i;
					$setValues [self::$paramAlias . $i] = $pk [$i];
				}
				$setExpress = '';
				foreach ( $columns as $columnName => $value ) {
					$setExpress .= ($setExpress ? ',' : ' ') . $columnName . '=' . self::$paramAlias . $j;
					$setValues [self::$paramAlias . $j] = $value;
					$j ++;
				}
				$sql = "UPDATE " . $this->_table . " SET {$setExpress}  WHERE " . $this->_pKey . " IN ({$idsExpress})";
// 				$affectRows = $command->createCommand ()->setSql ( $sql )->bindValues ( $setValues )->execute ();
				$affectSql = $command->createCommand ()->setSql ( $sql )->bindValues ( $setValues )->getRawSql();
				//操作记录--start
				$route = Yii::$app->controller->route;
				$controller = Yii::$app->controller->id;
				$action = Yii::$app->controller->action->id;
				AdminLog::saveLog($controller, $action, $route, $affectSql);
				//--end
				$affectRows = $command->createCommand($affectSql)->execute ();
				
			} else {
// 				$affectRows = $command->createCommand ()->update ( $this->_table, $columns, "`{$this->_table}`.`{$this->_pKey}` = :primartKey", array (
// 						':primartKey' => $pk 
// 				) )->execute ();
				$affectSql = $command->createCommand ()->update ( $this->_table, $columns, "`{$this->_table}`.`{$this->_pKey}` = :primartKey", array (
						':primartKey' => $pk 
				) )->getRawSql();
				//操作记录--start
				$route = Yii::$app->controller->route;
				$controller = Yii::$app->controller->id;
				$action = Yii::$app->controller->action->id;
				AdminLog::saveLog($controller, $action, $route, $affectSql);
				//--end
				$affectRows = $command->createCommand($affectSql)->execute ();
			}
			return $affectRows;
		} catch ( \Exception $e ) {
			return false;
		}
	}
	
	/**
	 * @desc 判断表名、主键、传入参数是否为空
	 * @param mixed 可变长参数列表
	 * @return boolean [true: 有参数为空；false: 没有空字段]
	 */
	public function isParamsEmpty($pk ,$columns){
		if(empty($this->_table) || empty($this->_pKey) || empty($pk) || empty($columns)){
			return true;
		}
		$paramArray = func_get_args();
		if(!empty($paramArray)){
			foreach ($paramArray as $param) {
				if(empty($param)){
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * @desc 检查是否有重名
	 * @param string $name 
	 * @param int $id  
	 * @author liaojianwen
	 * @date 2016-11-03
	 * @return boolean
	 */
	public function checkSameName($name,$id)
	{
		$query = new Query();
		$conditions ="{$this->_name} = '{$name}' and {$this->_dFlag} =".EnumOther::NO_DELETE;
		if ($id !== 0 ){
			$conditions .= " and {$this->_pKey} <> {$id}";
		}
		$result = $query->select ( $this->_pKey )->from ( "$this->_table" )->where ( $conditions )->all ();
		if (empty ( $result )) {
			return false;
		}
		return true;
	}
	
	/**
	 * @desc 根据条件判断记录是否存在，存在更新，不存在插入
	 * @param array $columns 列
	 * @param mixed $conditions 条件
	 * @param array $params 参数
	 * @param string $returnpk 返回自增ID
	 * @author liaojianwen
	 * @date 2016-11-25
	 * @return string|number|mixed
	 */
	public function ireplaceinto($columns, $conditions, $params, $returnpk = false)
	{
		try {
			$query = new Query ();
			
			$id = $query ->select($this->_pKey)
				->from($this->_table)
				->where($conditions, $params)
				->all();
			$command = Yii::$app->db;
			if (empty($id)) {
				if (! empty($this->_created) && ! isset($columns[$this->_created])) {
					$columns[$this->_created] = time();
				}
// 				$result = $command->createCommand()->insert($this->_table, $columns)->execute();
				$sql = $command->createCommand ()->insert($this->_table, $columns)->getRawSql();
				//操作记录--start
				$route = Yii::$app->controller->route;
				$controller = Yii::$app->controller->id;
				$action = Yii::$app->controller->action->id;
				AdminLog::saveLog($controller, $action, $route, $sql);
				//--end
				$result = $command->createCommand($sql)->execute ();
				if ($returnpk) {
					return $command->getLastInsertID();
				} else {
					return $result;
				}
			} else {
				if (! empty($this->_updated) && ! isset($columns[$this->_updated])) {
					$columns[$this->_updated] = time();
				}
// 				$result = $command->createCommand()->update($this->_table, $columns, $conditions, $params)->execute();
				$sql = $command->createCommand()->update($this->_table, $columns, $conditions, $params)->getRawSql();
				//操作记录--start
				$route = Yii::$app->controller->route;
				$controller = Yii::$app->controller->id;
				$action = Yii::$app->controller->action->id;
				AdminLog::saveLog($controller, $action, $route, $sql);
				//--end
				$result = $command->createCommand($sql)->execute ();
				if ($returnpk) {
					if (count($id) == 1) {
						$id = array_shift($id);
						$id = array_shift($id);
						return $id;
					} else {
						return $id;
					}
				} else {
					return $result;
				}
			}
		} catch (Exception $e) {
			return false;
		}
	}
}